﻿#region Using References

using System.Diagnostics.CodeAnalysis;
using System.Drawing;
using System.IO;
using Beaker.OpenCube.Game;
using Beaker.OpenCube.Resources;
using Beaker.OpenCube.Specs.Builders;
using Beaker.OpenCube.Textures;
using Beaker.Services.FileSystem;
using FluentAssertions;
using Microsoft.VisualStudio.TestTools.UnitTesting;

#endregion

namespace Beaker.OpenCube.Specs.Resources
{
	/// <summary>
	/// Summary description for ResourcePackReaderSepcs
	/// </summary>
	[TestClass]
	public class ResourcePackReaderSpecs
	{
		[ExcludeFromCodeCoverage]
		[TestMethod]
		public void PropertiesOfMetadataAreRead()
		{
			// arrange
			IFileSystemService folder =
				new FileSystemServiceBuilder()
					.WithFile( "pack.mcmeta", new TextStreamBuilder().WithText( @"{""pack"": {""pack_format"": 1,""description"": ""Some Description""}}" ).Build() )
					.Build();

			var reader = new ResourcePackReader( folder );

			// act
			ResourcePackMetadata meta = reader.ReadPackMetadata();

			// assert
			meta.Pack.PackFormat.Should().Be( 1 );
			meta.Pack.Description.Should().Be( "Some Description" );
		}

		[ExcludeFromCodeCoverage]
		[TestMethod]
		public void ReadingMetadataWillNotUseFallback()
		{
			// arrange
			IFileSystemService mainFolder =
				new FileSystemServiceBuilder()
					.Build();
			IFileSystemService fallbackFolder =
				new FileSystemServiceBuilder()
					.WithFile( "pack.mcmeta", new TextStreamBuilder().WithText( @"{""pack"": {""pack_format"": 1,""description"": ""Some Description""}}" ).Build() )
					.Build();

			var reader = new ResourcePackReader( mainFolder, fallbackFolder );

			// act
			ResourcePackMetadata meta = reader.ReadPackMetadata();

			// assert
			meta.Should().BeNull();
		}

		[TestMethod]
		public void ReadingPackImage()
		{
			// arrange
			Stream textureStream =
				GetType().Assembly.GetManifestResourceStream( GetType(), "DummyImage.png" );
			IFileSystemService mainFolder =
				new FileSystemServiceBuilder()
					.WithFile( "pack.png", textureStream )
					.Build();
			var reader = new ResourcePackReader( mainFolder );
			
			// act
			Bitmap image = reader.ReadPackImage();

			// assert
			image.Should().NotBeNull();
		}

		[TestMethod]
		public void ReadingPackImageShouldNotUseFallback()
		{
			// arrange
			Stream textureStream =
				GetType().Assembly.GetManifestResourceStream( GetType(), "DummyImage.png" );
			IFileSystemService mainFolder =
				new FileSystemServiceBuilder()
					.Build();
			IFileSystemService fallbackFolder =
				new FileSystemServiceBuilder()
					.WithFile( "pack.png", textureStream )
					.Build();
			var reader = new ResourcePackReader( mainFolder, fallbackFolder );

			// act
			Bitmap image = reader.ReadPackImage();

			// assert
			image.Should().BeNull();
		}

		[TestMethod]
		public void BlockTexture()
		{
			// arrange
			Stream textureStream =
				GetType().Assembly.GetManifestResourceStream( GetType(), "DummyImage.png" );
			IFileSystemService mainFolder =
				new FileSystemServiceBuilder()
					.WithFile( "assets/minecraft/textures/blocks/stone.png", textureStream )
					.Build();

			var reader = new ResourcePackReader( mainFolder );

			// act
			BlockTexture blockTexture = reader.ReadBlockTexture( Block.Stone );

			// assert
			blockTexture.Should().NotBeNull();
			blockTexture.Textures[BlockTextureFlags.Top].Image.Should().NotBeNull();
		}

		[TestMethod]
		public void BlockTextureShouldFallBack()
		{
			// arrange
			Stream textureStream =
				GetType().Assembly.GetManifestResourceStream( GetType(), "DummyImage.png" );
			IFileSystemService mainFolder =
				new FileSystemServiceBuilder()
					.WithFile( "assets/minecraft/textures/blocks/other.png", textureStream )
					.Build();
			IFileSystemService fallbackFolder =
				new FileSystemServiceBuilder()
					.WithFile( "assets/minecraft/textures/blocks/stone.png", textureStream )
					.Build();

			var reader = new ResourcePackReader( mainFolder, fallbackFolder );

			// act
			BlockTexture blockTexture = reader.ReadBlockTexture( Block.Stone );

			// assert
			blockTexture.Should().NotBeNull();
			blockTexture.Textures[BlockTextureFlags.Top].Image.Should().NotBeNull();
		}
	}
}
